package com.wx.house.common.aop;

import com.github.pagehelper.PageHelper;
import com.wx.house.core.pojo.base.Page;
import com.wx.house.core.pojo.base.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;

/**
 * @Author ：罗棋
 * @Email ：58428467@qq.com
 * @date ：Created in 2019/10/29 上午 09:45
 * @description： 分页aop类
 * @version: ：V
 */
@Component
@Aspect
@Slf4j
public class TerminalPageHelperAop {

@Pointcut("execution(public * com.wx.house.*.api.controller.v1.*Controller.*(..))")
public void PageAop() {
}

@Around("PageAop()")
public <T> Result<T> controllerAop(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
	HttpServletRequest request;
	try {
		request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
	} catch (NullPointerException n) {
		return (Result<T>) proceedingJoinPoint.proceed();
	}
	
	Object[] args = proceedingJoinPoint.getArgs();
	//获取类名
	String clazzName = proceedingJoinPoint.getTarget().getClass().getName();
	//获取方法名称
	String methodName = proceedingJoinPoint.getSignature().getName();
	
	//生成controller实例
	Class<?> aClass = Class.forName(clazzName);
	//获取controller中方法
	Method[] methods = aClass.getMethods();
	String baseMapping = String.join("", aClass.getAnnotation(RequestMapping.class).value());
	Page page = null;
	
	for (Method method : methods) {//方法名相同
		if (page != null) break;
		for (Annotation annotation : method.getAnnotations()) {//RequestMapping相同
			String annotationName = annotation.annotationType().getName().toUpperCase();
			String requestMethod = request.getMethod().toUpperCase();
			if (annotationName.contains(requestMethod)) {
				StringBuffer requestURL = request.getRequestURL();
				String[] pathString = this.requestMapping(method, requestMethod);
				String mappingUrl = String.join("", Arrays.asList(pathString));
				String mapping = baseMapping + mappingUrl;
				if (requestURL.toString().contains(mapping)) {
					log.info("PageHelperAop >> 开始分页");
					for (Object arg : args) {
						try {
							page = (Page) arg;//尝试将参数转成Page类，所有的page类都需要继承自com.wx.house.common.base.Page
							if (page != null) break;//转换成功则不再继续寻找
						} catch (Exception ignored) {
						}
					}
				}
			}
		}
	}
	
	//如果需要手动关闭分页，自己实现分页
	if (methodName.contains("Nap") || page == null) return (Result<T>) proceedingJoinPoint.proceed();
	
	PageHelper.startPage(page.getPage(), page.getPageSize());
	return (Result<T>) proceedingJoinPoint.proceed();
}

private String[] requestMapping(Method method, String requestMethod) {
	if (requestMethod.equals("GET")) {
		return method.getAnnotation(GetMapping.class).path();
	}
	if (requestMethod.equals("POST")) {
		return method.getAnnotation(PostMapping.class).path();
	}
	if (requestMethod.equals("PUT")) {
		return method.getAnnotation(PutMapping.class).path();
	}
	if (requestMethod.equals("DELETE")) {
		return method.getAnnotation(DeleteMapping.class).path();
	}
	return null;
}
}
